cargo bench [options] [--] [<args>...]
Options:
- -h, --help Print this message
- --no-run Compile, but don't run benchmarks
- -j N, --jobs N The number of jobs to run in parallel
- --features FEATURES Space-separated list of features to also build
- --no-default-features Do not build the `default` feature
- --target TRIPLE Build for the target triple
- --manifest-path PATH Path to the manifest to build benchmarks for
- -v, --verbose Use verbose output
+ -h, --help Print this message
+ --no-run Compile, but don't run benchmarks
+ -p SPEC, --package SPEC Package to run benchmarks for
+ -j N, --jobs N The number of jobs to run in parallel
+ --features FEATURES Space-separated list of features to also build
+ --no-default-features Do not build the `default` feature
+ --target TRIPLE Build for the target triple
+ --manifest-path PATH Path to the manifest to build benchmarks for
+ -v, --verbose Use verbose output
All of the trailing arguments are passed to the benchmark binaries generated
for filtering benchmarks and generally providing options configuring how they
run.
+
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be benchmarked. If it is not given, then
+the current package is benchmarked. For more information on SPEC and its format,
+see the `cargo help pkgid` command.
", flag_jobs: Option<uint>, flag_target: Option<String>,
- flag_manifest_path: Option<String>, flag_features: Vec<String>)
+ flag_manifest_path: Option<String>, flag_features: Vec<String>,
+ flag_package: Option<String>)
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
dev_deps: true,
features: options.flag_features.as_slice(),
no_default_features: options.flag_no_default_features,
- spec: None,
+ spec: options.flag_package.as_ref().map(|s| s.as_slice()),
},
};
Compile a local package and all of its dependencies
Usage:
- cargo build [options] [<spec>]
+ cargo build [options]
Options:
- -h, --help Print this message
- -j N, --jobs N The number of jobs to run in parallel
- --release Build artifacts in release mode, with optimizations
- --features FEATURES Space-separated list of features to also build
- --no-default-features Do not build the `default` feature
- --target TRIPLE Build for the target triple
- --manifest-path PATH Path to the manifest to compile
- -v, --verbose Use verbose output
-
-If <spec> is given, then only the package specified will be build (along with
-all its dependencies). If <spec> is not given, then the current package will be
-built.
-
-For more information about the format of <spec>, see `cargo help pkgid`.
+ -h, --help Print this message
+ -p SPEC, --package SPEC Package to run benchmarks for
+ -j N, --jobs N The number of jobs to run in parallel
+ --release Build artifacts in release mode, with optimizations
+ --features FEATURES Space-separated list of features to also build
+ --no-default-features Do not build the `default` feature
+ --target TRIPLE Build for the target triple
+ --manifest-path PATH Path to the manifest to compile
+ -v, --verbose Use verbose output
+
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be built. If it is not given, then the
+current package built tested. For more information on SPEC and its format, see the
+`cargo help pkgid` command.
", flag_jobs: Option<uint>, flag_target: Option<String>,
flag_manifest_path: Option<String>, flag_features: Vec<String>,
- arg_spec: Option<String>)
+ flag_package: Option<String>)
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
debug!("executing; cmd=cargo-build; args={}", os::args());
dev_deps: false,
features: options.flag_features.as_slice(),
no_default_features: options.flag_no_default_features,
- spec: options.arg_spec.as_ref().map(|s| s.as_slice()),
+ spec: options.flag_package.as_ref().map(|s| s.as_slice()),
};
ops::compile(&root, &mut opts).map(|_| None).map_err(|err| {
Remove artifacts that cargo has generated in the past
Usage:
- cargo clean [options] [<spec>]
+ cargo clean [options]
Options:
- -h, --help Print this message
- --manifest-path PATH Path to the manifest to the package to clean
- --target TRIPLE Target triple to clean output for (default all)
- -v, --verbose Use verbose output
-
-If <spec> is provided, then it is interpreted as a package id specification and
-only the output for the package specified will be removed. If <spec> is not
-provided, then all output from cargo will be cleaned out. Note that a lockfile
-must exist for <spec> to be given.
-
-For more information about <spec>, see `cargo help pkgid`.
-", flag_manifest_path: Option<String>, arg_spec: Option<String>,
+ -h, --help Print this message
+ -p SPEC, --package SPEC Package to run benchmarks for
+ --manifest-path PATH Path to the manifest to the package to clean
+ --target TRIPLE Target triple to clean output for (default all)
+ -v, --verbose Use verbose output
+
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package's artifacts should be cleaned out. If it is not
+given, then all packages' artifacts are removed. For more information on SPEC
+and its format, see the `cargo help pkgid` command.
+", flag_manifest_path: Option<String>, flag_package: Option<String>,
flag_target: Option<String>)
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
let mut opts = ops::CleanOptions {
shell: shell,
- spec: options.arg_spec.as_ref().map(|s| s.as_slice()),
+ spec: options.flag_package.as_ref().map(|s| s.as_slice()),
target: options.flag_target.as_ref().map(|s| s.as_slice()),
};
ops::clean(&root, &mut opts).map(|_| None).map_err(|err| {
cargo test [options] [--] [<args>...]
Options:
- -h, --help Print this message
- --no-run Compile, but don't run tests
- -j N, --jobs N The number of jobs to run in parallel
- --features FEATURES Space-separated list of features to also build
- --no-default-features Do not build the `default` feature
- --target TRIPLE Build for the target triple
- --manifest-path PATH Path to the manifest to build tests for
- -v, --verbose Use verbose output
+ -h, --help Print this message
+ --no-run Compile, but don't run tests
+ -p SPEC, --package SPEC Package to run tests for
+ -j N, --jobs N The number of jobs to run in parallel
+ --features FEATURES Space-separated list of features to also build
+ --no-default-features Do not build the `default` feature
+ --target TRIPLE Build for the target triple
+ --manifest-path PATH Path to the manifest to build tests for
+ -v, --verbose Use verbose output
All of the trailing arguments are passed to the test binaries generated for
filtering tests and generally providing options configuring how they run.
+
+If the --package argument is given, then SPEC is a package id specification
+which indicates which package should be tested. If it is not given, then the
+current package is tested. For more information on SPEC and its format, see the
+`cargo help pkgid` command.
", flag_jobs: Option<uint>, flag_target: Option<String>,
- flag_manifest_path: Option<String>, flag_features: Vec<String>)
+ flag_manifest_path: Option<String>, flag_features: Vec<String>,
+ flag_package: Option<String>)
pub fn execute(options: Options, shell: &mut MultiShell) -> CliResult<Option<()>> {
let root = try!(find_root_manifest_for_cwd(options.flag_manifest_path));
dev_deps: true,
features: options.flag_features.as_slice(),
no_default_features: options.flag_no_default_features,
- spec: None,
+ spec: options.flag_package.as_ref().map(|s| s.as_slice()),
},
};
log!(4, "compile; manifest-path={}", manifest_path.display());
+ if spec.is_some() && (no_default_features || features.len() > 0) {
+ return Err(human("features cannot be modified when the main package \
+ is not being built"))
+ }
+
let mut source = try!(PathSource::for_path(&manifest_path.dir_path()));
try!(source.update());
Job { dirty: dirty, fresh: fresh, desc: desc }
}
+ /// Create a new job which will run `fresh` if the job is fresh and
+ /// otherwise not run `dirty`.
+ ///
+ /// Retains the same signature as `new` for compatibility. This job does not
+ /// describe itself to the console.
+ pub fn noop(_dirty: proc():Send -> CargoResult<()>,
+ fresh: proc():Send -> CargoResult<()>,
+ _desc: String) -> Job {
+ Job { dirty: proc() Ok(()), fresh: fresh, desc: String::new() }
+ }
+
/// Consumes this job by running it, returning the result of the
/// computation.
pub fn run(self, fresh: Freshness) -> CargoResult<()> {
-use std::collections::HashMap;
-use std::collections::hashmap::{Occupied, Vacant};
+use std::collections::hashmap::{HashMap, HashSet, Occupied, Vacant};
use term::color::YELLOW;
use core::{Package, PackageId, Resolve};
active: uint,
pending: HashMap<(&'a PackageId, TargetStage), PendingBuild>,
state: HashMap<&'a PackageId, Freshness>,
+ ignored: HashSet<&'a PackageId>,
}
/// A helper structure for metadata about the state of a building package.
active: 0,
pending: HashMap::new(),
state: HashMap::new(),
+ ignored: HashSet::new(),
}
}
(pkg, jobs));
}
+ pub fn ignore(&mut self, pkg: &'a Package) {
+ self.ignored.insert(pkg.get_package_id());
+ }
+
/// Execute all jobs necessary to build the dependency graph.
///
/// This function will spawn off `config.jobs()` workers to build all of the
let amt = if njobs == 0 {1} else {njobs};
let id = pkg.get_package_id().clone();
- if stage == StageStart {
+ if stage == StageStart && !self.ignored.contains(&pkg.get_package_id()) {
match fresh.combine(self.state[pkg.get_package_id()]) {
Fresh => try!(config.shell().verbose(|c| {
c.status("Fresh", pkg)
// particular package. No actual work is executed as part of this, that's
// all done later as part of the `execute` function which will run
// everything in order with proper parallelism.
- let mut dep_pkgids = HashSet::new();
+ let mut compiled = HashSet::new();
each_dep(pkg, &cx, |dep| {
- dep_pkgids.insert(dep.get_package_id().clone());
+ compiled.insert(dep.get_package_id().clone());
});
for dep in deps.iter() {
if dep == pkg { continue }
- if !dep_pkgids.contains(dep.get_package_id()) { continue }
// Only compile lib targets for dependencies
let targets = dep.get_targets().iter().filter(|target| {
cx.is_relevant_target(*target)
}).collect::<Vec<&Target>>();
- if targets.len() == 0 {
+ if targets.len() == 0 && dep.get_package_id() != resolve.root() {
return Err(human(format!("Package `{}` has no library targets", dep)))
}
- try!(compile(targets.as_slice(), dep, &mut cx, &mut queue));
+ let compiled = compiled.contains(dep.get_package_id());
+ try!(compile(targets.as_slice(), dep, compiled, &mut cx, &mut queue));
}
if pkg.get_package_id() == resolve.root() {
cx.primary();
}
- try!(compile(targets, pkg, &mut cx, &mut queue));
+ try!(compile(targets, pkg, true, &mut cx, &mut queue));
// Now that we've figured out everything that we're going to do, do it!
try!(queue.execute(cx.config));
}
fn compile<'a, 'b>(targets: &[&'a Target], pkg: &'a Package,
+ compiled: bool,
cx: &mut Context<'a, 'b>,
jobs: &mut JobQueue<'a, 'b>) -> CargoResult<()> {
debug!("compile_pkg; pkg={}; targets={}", pkg, targets);
let _p = profile::start(format!("preparing: {}", pkg));
+ // Packages/targets which are actually getting compiled are constructed into
+ // a real job. Packages which are *not* compiled still have their jobs
+ // executed, but only if the work is fresh. This is to preserve their
+ // artifacts if any exist.
+ let job = if compiled {Job::new} else {Job::noop};
+ if !compiled { jobs.ignore(pkg); }
+
if targets.is_empty() {
return Ok(())
}
for cmd in build_cmds.into_iter() { try!(cmd()) }
dirty()
};
- jobs.enqueue(pkg, StageCustomBuild, vec![(Job::new(dirty, fresh, desc),
+ jobs.enqueue(pkg, StageCustomBuild, vec![(job(dirty, fresh, desc),
freshness)]);
// After the custom command has run, execute rustc for all targets of our
try!(fingerprint::prepare_target(cx, pkg, target, kind));
let dirty = proc() { try!(work()); dirty() };
- dst.push((Job::new(dirty, fresh, desc), freshness));
+ dst.push((job(dirty, fresh, desc), freshness));
}
}
jobs.enqueue(pkg, StageLibraries, libs);
COMPILING, p.url())));
// Make sure clean only cleans one dep
- assert_that(p.process(cargo_dir().join("cargo")).arg("clean").arg("foo"),
+ assert_that(p.process(cargo_dir().join("cargo")).arg("clean")
+ .arg("-p").arg("foo"),
execs().with_stdout(""));
assert_that(p.process(cargo_dir().join("cargo")).arg("build"),
execs().with_stdout(format!("{} foo v0.5.0 ({})\n",
assert_that(p.process(cargo_dir().join("cargo")).arg("clean"),
execs().with_stdout(""));
println!("building baz");
- assert_that(p.process(cargo_dir().join("cargo")).arg("build").arg("baz"),
+ assert_that(p.process(cargo_dir().join("cargo")).arg("build")
+ .arg("-p").arg("baz"),
execs().with_stdout(format!("{} baz v0.5.0 ({})\n",
COMPILING, p.url())));
println!("building foo");
- assert_that(p.process(cargo_dir().join("cargo")).arg("build").arg("foo"),
+ assert_that(p.process(cargo_dir().join("cargo")).arg("build")
+ .arg("-p").arg("foo"),
execs().with_stdout(format!("{} bar v0.5.0 ({})\n\
{} foo v0.5.0 ({})\n",
COMPILING, p.url(),
compiling = COMPILING, running = RUNNING,
dir = p.url()).as_slice()));
})
+
+test!(selective_testing {
+ let p = project("foo")
+ .file("Cargo.toml", r#"
+ [package]
+ name = "foo"
+ version = "0.0.1"
+ authors = []
+
+ [dependencies.d1]
+ path = "d1"
+ [dependencies.d2]
+ path = "d2"
+
+ [lib]
+ name = "foo"
+ doctest = false
+ "#)
+ .file("src/lib.rs", "")
+ .file("d1/Cargo.toml", r#"
+ [package]
+ name = "d1"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "d1"
+ doctest = false
+ "#)
+ .file("d1/src/lib.rs", "")
+ .file("d2/Cargo.toml", r#"
+ [package]
+ name = "d2"
+ version = "0.0.1"
+ authors = []
+
+ [lib]
+ name = "d2"
+ doctest = false
+ "#)
+ .file("d2/src/lib.rs", "");
+ p.build();
+
+ println!("d1");
+ assert_that(p.process(cargo_dir().join("cargo")).arg("test")
+ .arg("-p").arg("d1"),
+ execs().with_status(0)
+ .with_stderr("")
+ .with_stdout(format!("\
+{compiling} d1 v0.0.1 ({dir})
+{running} target[..]d1-[..]
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured\n
+", compiling = COMPILING, running = RUNNING,
+ dir = p.url()).as_slice()));
+
+ println!("d2");
+ assert_that(p.process(cargo_dir().join("cargo")).arg("test")
+ .arg("-p").arg("d2"),
+ execs().with_status(0)
+ .with_stderr("")
+ .with_stdout(format!("\
+{compiling} d2 v0.0.1 ({dir})
+{running} target[..]d2-[..]
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured\n
+", compiling = COMPILING, running = RUNNING,
+ dir = p.url()).as_slice()));
+
+ println!("whole");
+ assert_that(p.process(cargo_dir().join("cargo")).arg("test"),
+ execs().with_status(0)
+ .with_stderr("")
+ .with_stdout(format!("\
+{compiling} foo v0.0.1 ({dir})
+{running} target[..]foo-[..]
+
+running 0 tests
+
+test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured\n
+", compiling = COMPILING, running = RUNNING,
+ dir = p.url()).as_slice()));
+})